package com.xiguthings.waka.web.controller.user;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import com.xiguthings.waka.dao.DataBaseStatus;
import com.xiguthings.waka.exception.HttpSendErrorException;
import com.xiguthings.waka.po.CoolDownCard;
import com.xiguthings.waka.po.CoolDownCardExample;
import com.xiguthings.waka.po.UserExample;
import com.xiguthings.waka.po.extpo.Page;
import com.xiguthings.waka.shiro.CustomizedToken;
import com.xiguthings.waka.web.controller.cdcard.CDcardVo;
import com.xiguthings.waka.web.controller.wechat.wx.WxConnExec;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.xiguthings.waka.exception.BussinessException;
import com.xiguthings.waka.po.User;
import com.xiguthings.waka.publicUtils.StringUtils;
import com.xiguthings.waka.service.user.IUserService;
import com.xiguthings.waka.web.controller.base.AbstractController;
import com.xiguthings.waka.web.controller.base.ResponseEntity;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/user")
@Api(tags = "用户")
public class UserController extends AbstractController {

    @Resource
    private IUserService userService;


    /**
     * 创建查询条件
     *
     * @param userVo
     * @param example
     * @throws NumberFormatException
     */
    private UserExample.Criteria queryConditions(UserVo userVo, UserExample example) throws NumberFormatException {

        UserExample.Criteria criteria = example.createCriteria();
        // 如果查询条件为空的
        if (userVo == null) {
            // 则查询所有未被删除的
            criteria.andStatusNotEqualTo(DataBaseStatus.DELETE);
            return criteria;
        }

        // 如果有查询条件
        User user = userVo.getUser();
        // 添加查询条件
        if (user != null) {

            if (StringUtils.isNotBlank(user.getUserId())) {
                criteria.andUserIdEqualTo(user.getUserId());
            }
            if (StringUtils.isNotBlank(user.getOpenid())) {
                criteria.andOpenidEqualTo(user.getOpenid());
            }
            if (StringUtils.isNotBlank(user.getChildNickname())) {
                criteria.andChildNicknameLike("%" + user.getChildNickname() + "%");
            }
        }

        if (userVo.getBeginCDtime() != null) {
            criteria.andCdBeginTimeGreaterThanOrEqualTo(userVo.getBeginCDtime());
        }
        if (userVo.getEndCDtime() != null) {
            criteria.andCdBeginTimeLessThanOrEqualTo(userVo.getEndCDtime());
        }

        if (StringUtils.isNotBlank(userVo.getInStatus())) {
            // 添加包含的状态
            String statuses = userVo.getInStatus();
            String[] statusArr = statuses.split(",");
            List<Integer> statusList = new ArrayList<>();
            for (String str : statusArr) {
                statusList.add(new Integer(str));
            }
            criteria.andStatusIn(statusList);
        } else {
            // 如果状态的查询条件是空的，则查询没有被删除的
            criteria.andStatusNotEqualTo(DataBaseStatus.DELETE);
        }

        return criteria;
    }


    @ApiOperation(tags = {"1.控制台",
            "2.用户端"}, value = "根据主键或者微信标识查询用户详情", httpMethod = "GET", notes = "userId或者openid必填一个", response = ResponseEntity.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user.userId", value = "主键id", dataType = "String", required = false, paramType = "query"),
            @ApiImplicitParam(name = "user.openid", value = "微信标识", dataType = "String", required = false, paramType = "query")})
    @RequestMapping("/detail")
    @ResponseBody
    public ResponseEntity detail(@ApiIgnore UserVo userVo) throws Exception {
        String userId = null;
        String openid = null;
        User user = null;
        if (userVo != null && userVo.getUser() != null) {
            if (StringUtils.isNotBlank((userId = userVo.getUser().getUserId()))) {

                user = userService.selectByPrimaryKey(userId);

            } else if (StringUtils.isNotBlank((openid = userVo.getUser().getOpenid()))) {

                user = userService.selectByOpenid(openid);

            } else {
                BussinessException bet = new BussinessException("userId,openid都是空参数");
                bet.setCode(CODE_EMPTY_REQUIRED);
                throw bet;
            }

        }

        return ajaxReturnMap(CODE_SUCCESS, "", user);

    }

    /**
     * 修改或者添加
     *
     * @param userVo
     * @return
     * @throws Exception
     */
    @ApiOperation(tags = {
            "1.控制台", "2.用户端"}, value = "修改/添加", httpMethod = "POST", notes = "修改时，必须填写“user.userId”参数,新增用户时，必须填写user.openid", response = ResponseEntity.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user.userId", value = "主键id", dataType = "String", required = false, paramType = "query"),
            @ApiImplicitParam(name = "user.childNickname", value = "昵称", dataType = "string", required = false, paramType = "query"),
            @ApiImplicitParam(name = "user.openid", value = "微信唯一标识", dataType = "string", required = false, paramType = "query")})
    @RequestMapping("/save")
    @ResponseBody
    public ResponseEntity save(@ApiIgnore UserVo userVo) throws Exception {

        if (userVo == null || userVo.getUser() == null) {
            BussinessException bet = new BussinessException("空参数");
            bet.setCode(CODE_EMPTY_REQUIRED);
            throw bet;
        }

        String msg = "";
        User user = userVo.getUser();

        if (StringUtils.isNotBlank(user.getUserId())) {
            // updata 只能够修改用户的昵称
            if (StringUtils.isBlank(user.getChildNickname())) {
                BussinessException bet = new BussinessException("修改昵称，不能为空字符");
                bet.setCode(CODE_EMPTY_REQUIRED);
                throw bet;
            }
            User saveUser = new User();
            saveUser.setChildNickname(user.getChildNickname());
            saveUser.setUserId(user.getUserId());
            userService.updateByPrimaryKeySelective(saveUser);
            msg = "修改成功";
        } else {
            // insert
            String openid = null;
            if (StringUtils.isBlank(openid = user.getOpenid())) {
                BussinessException bet = new BussinessException("openid不能为空");
                bet.setCode(CODE_EMPTY_REQUIRED);
                throw bet;
            }
            //判断openid是否已经存在了
            if (userService.selectByOpenid(openid) != null) {
                BussinessException bet = new BussinessException("修改昵称，请传输userId的值");
                bet.setCode(CODE_EMPTY_REQUIRED);
                throw bet;
            }


            userService.insert(userVo.getUser());
            msg = "添加成功";
        }
        String id = user.getUserId();
        return ajaxReturnMap(CODE_SUCCESS, msg, id);
    }

    @ApiOperation(tags = {"1.控制台"}, value = "分页查询", httpMethod = "GET", notes = "可根据条件进行筛选", response = ResponseEntity.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user.userId", value = "主键id", dataType = "String", required = false, paramType = "query"),
            @ApiImplicitParam(name = "user.openid", value = "微信标识", dataType = "String", required = false, paramType = "query"),
            @ApiImplicitParam(name = "user.childNickname", value = "孩子昵称", dataType = "string", required = false, paramType = "query"),
            @ApiImplicitParam(name = "beginCDtime", value = "过滤 冷却开始时间 的开始(yyyy-MM-dd hh:mm:ss)", dataType = "string", required = false, paramType = "query"),
            @ApiImplicitParam(name = "endCDtime", value = "过滤 冷却开始时间 的结束(yyyy-MM-dd hh:mm:ss)", dataType = "string", required = false, paramType = "query"),
            @ApiImplicitParam(name = "inStatus", value = "状态：0--正常，99--删除", dataType = "int", required = false, paramType = "query"),
            @ApiImplicitParam(name = "page", value = "页码，如果没有值，则使用默认值。开始值从 1 开始计算", dataType = "int", required = false, paramType = "query"),
            @ApiImplicitParam(name = "rows", value = "每页的数量,如果没有值，则使用默认值", dataType = "int", required = false, paramType = "query")})
    @RequestMapping("/pagelist")
    @ResponseBody
    public ResponseEntity pageList(@ApiIgnore UserVo userVo, @ApiIgnore Page page) throws Exception {
        UserExample example = new UserExample();
        queryConditions(userVo, example);
        super.selectByPage(page, example, userService);
        return ajaxReturnMap(CODE_SUCCESS, null, page);
    }


    @ApiOperation(tags = {"2.用户端"}, value = "小程序登录", httpMethod = "GET", notes = "loginCode必填,登录成功后返回参数中 data：<br>{openid:string,sessionId:string,userId:string}", response = ResponseEntity.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "loginCode", value = "loginCode", dataType = "String", required = true, paramType = "query")
    })
    @RequestMapping("/login")
    @ResponseBody
    public ResponseEntity login(@ApiIgnore String loginCode) throws Exception {
        if (StringUtils.isBlank(loginCode)) {
            throwHttpSendErrorExceptionException(CODE_NOT_LOGIN, "loginCode为空");
        }
        String openid = null;
        CustomizedToken tk = new CustomizedToken(null, null, Key_loginType_user, loginCode);
        Subject subject = SecurityUtils.getSubject(); // 得到当前用户
        try {
            subject.login(tk); // 自动调用AuthRealm.doGetAuthenticationInfo
        } catch (AuthenticationException e) {
            throwHttpSendErrorExceptionException(CODE_NOT_LOGIN, "登录失败");
        }

        openid = (String) tk.getParam().get("openid");
        if (StringUtils.isBlank(openid)) {
            throwHttpSendErrorExceptionException(CODE_NOT_LOGIN, "登录失败");
        }
        User user = userService.selectByOpenid(openid);
        HttpSession session = super.getSession();
        session.setAttribute(SESSION_CRN_USER, user);

        Map<String, Object> map = new HashMap<>(2);

        map.put("openid", openid);
        map.put("sessionId", session.getId());
        if (user != null) {
            map.put("userId", user.getUserId());
        }

        return ajaxReturnMap(CODE_SUCCESS, null, map);
    }
}
